// 纹理创建步骤 ：
// 方法一：1、纹理加载器 2、创建纹理 3、设置material
// 方法二：1、创建纹理传递图像url const texture = new THREE.Texture(图像) 2、图像加载完成时更新纹理image.onLoad=()=>{texture.needsUpdate=true}
// 加载管理器 LoadingManager
// UV展开：
// 纹理是通过uv坐标放置在几何体上的
// 几何体属性：normal法线 position（Vector3） uv（Vector2）
// 纹理变换：重复、包裹、偏移、旋转、中心
// 纹理过滤器：

import React, { useEffect, useRef } from 'react';
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { GUI } from 'lil-gui';
import doorTextureUrl from '@/assets/texture/blackAndWhite.png';
export default function index() {
  const mountRef = useRef(null);
  const gui = new GUI();

  useEffect(() => {
    const scene = new THREE.Scene();

    const camera = new THREE.PerspectiveCamera(
      75,
      window.innerWidth / window.innerHeight,
      0.1,
      1000
    );
    camera.position.set(1, 1, 5);
    scene.add(camera);
    // 创建纹理
    // 1、创建纹理加载器 一个纹理加载器可以加载多个纹理THREE.TextureLoader().load(图像,加载时回调，进度时回调，错误时回调)
    const textureLoader = new THREE.TextureLoader();
    // 2、创建纹理
    const texture = textureLoader.load(doorTextureUrl);
    // 3、设置在material中 {map：texture}
    const boxgem = new THREE.BoxGeometry(1, 1, 1);
    const material = new THREE.MeshBasicMaterial({
      map: texture,
    });
    const mesh = new THREE.Mesh(boxgem, material);
    scene.add(mesh);
    console.log(boxgem); // 几何体属性：normal法线 position（Vector3） uv（Vector2）
    const renderer = new THREE.WebGLRenderer();
    renderer.setSize(window.innerWidth, window.innerHeight);
    mountRef.current.appendChild(renderer.domElement);
    renderer.render(scene, camera);

    // 加载管理器
    const loadingManager = new THREE.LoadingManager();
    loadingManager.onStart = () => {
      console.log('开始加载');
    };
    loadingManager.onLoad = () => {
      console.log('加载完成');
    };
    loadingManager.onProgress = () => {
      console.log('加载中');
    };
    loadingManager.onError = () => {
      console.log('加载失败');
    };

    // 纹理过滤器：
    // minFilter: 当纹理缩小时使用最近邻过滤,保持像素的清晰边缘
    texture.minFilter = THREE.NearestFilter;
    // magFilter: 当纹理放大时使用线性过滤,平滑像素之间的过渡
    texture.magFilter = THREE.LinearFilter;
    // 禁用mipmap ： 使用纹理过滤器时禁用mipmap会提升性能
    texture.generateMipmaps = false;

    // 纹理变换
    // 1、重复 纹理在模型表面的平铺次数，水平、垂直向
    // texture.repeat.x = 2;  // 需要搭配 wrapS
    // texture.repeat.y = 3; // 需要搭配 wrapT
    // // 2、包裹 RepeatWrapping纹理无限重复
    // texture.wrapS = THREE.RepeatWrapping;
    // texture.wrapT = THREE.RepeatWrapping;
    // 偏移 Vector2
    // texture.offset.x = 0.5;
    // texture.offset.y = 0.5;
    // 旋转
    // UV坐标系统中,纹理坐标的范围是0到1
    // (0,0)表示纹理左下角,(1,1)表示纹理右上角
    // 默认旋转中心是(0,0),即纹理的左下角
    // 设置center为(0.5,0.5)就将旋转中心移到了纹理的正中心位置
    // texture.center.x = 0.5;
    // texture.center.y = 0.5;
    // texture.rotation = Math.PI * 0.25;

    const axis = new OrbitControls(camera, renderer.domElement);

    // gui
    gui.add(mesh.position, 'y').min(-3).max(3).step(0.1);
    gui.add(mesh.position, 'x').min(-3).max(3).step(0.1);
    gui.add(mesh.position, 'z').min(-3).max(3).step(0.1);
    gui.add(mesh, 'visible');
    gui.add(material, 'wireframe');

    const animation = () => {
      axis.update();
      renderer.render(scene, camera);
      window.requestAnimationFrame(animation);
    };
    animation();
  }, []);

  return (
    <div
      ref={mountRef}
      style={{ width: '100%' }}
    />
  );
}
